﻿using System;

namespace CoreTypes
{
   public class DefaultEventArgs : EventArgs
   {
      public readonly object EventData;

      public DefaultEventArgs(object e)
      {
         EventData = e;
      }
   }

   public class AccountAddedEventArgs : EventArgs
   {
      public Account Account;

      public bool IsNew;
      public bool Activated;

      public AccountAddedEventArgs(Account account, bool isNew, bool activated)
      {
         Account = account;
         IsNew = isNew;
         Activated = activated;
      }
   }

   public class StatusChangedEventArgs : EventArgs
   {
      public Account Account;

      public Status Status;

      public StatusChangedEventArgs(Account account, Status status)
      {
         Account = account;
         Status = status;
      }
   }

   public class AccountRemovedEventArgs : EventArgs
   {
      public Account Account;

      public bool Dropped;
      public bool Deactivated;

      public AccountRemovedEventArgs(Account account, bool dropped, bool deactivated)
      {
         Account = account;
         Dropped = dropped;
         Deactivated = deactivated;
      }
   }

   public class ContactsLoadedEventArgs : EventArgs
   {
      public Account Owner;
      public bool Remote;

      public ContactsLoadedEventArgs(Account owner, bool remote)
      {
         Owner = owner;
         Remote = remote;
      }
   }

   public class MessageAcceptedEventArgs : EventArgs
   {
      public readonly ServiceMessage Message;

      public MessageAcceptedEventArgs(ServiceMessage message)
      {
         Message = message;
      }
   }
   
   public class ContactsChangedEventArgs : EventArgs
   {
      public string Name;
      public Account Owner;
      public Contact Contact;
      public ContactGroup Group;
      public ActionSource ActionSource;

      public ContactsChangedActions Actions;

      // Rename group
      public ContactsChangedEventArgs(ContactGroup group, string oldName)
      {
         Group = group;
         Name = oldName;
         Owner = group.Owner;
         Actions = ContactsChangedActions.Modify;
      }

      // Modify (add, remove) group
      public ContactsChangedEventArgs(ContactGroup group, ContactsChangedActions actions)
      {
         Group = group;
         Owner = group.Owner;
         Actions = actions;
      }

      // Modify (add, remove) contact
      public ContactsChangedEventArgs(Contact contact, ContactsChangedActions actions)
      {
         Contact = contact;
         Owner = contact.Owner;
         Group = contact.Group;
         Actions = actions;
      }

      // Removing or block contact
      public ContactsChangedEventArgs(Contact contact, Account owner, bool remove, bool block)
      {
         Owner = owner;
         Contact = contact;
         if (block) Actions |= ContactsChangedActions.Block;
         Actions |= remove ? ContactsChangedActions.Remove : ContactsChangedActions.Hide;
      }

      // Moving contact
      public ContactsChangedEventArgs(Contact contact, ContactGroup oldGroup, ActionSource source)
      {
         Group = oldGroup;
         Contact = contact;
         Owner = contact.Owner;
         ActionSource = source;
         Actions = ContactsChangedActions.Move;
      }
   }

   public class NetworkOperationEventArgs : EventArgs
   {
      protected OperationState FState;
      protected NetworkOperation FOperation;
      protected ServiceOperationException FError;

      public Account Account
      {
         get
         {
            return FOperation != null ? FOperation.Account : null;
         }
      }
      public OperationState State
      {
         get
         {
            return FOperation == null ? FState : FOperation.State;
         }
      }
      public NetworkOperation Operation
      {
         get
         {
            return FOperation;
         }
      }
      public ServiceOperationException Error
      {
         get
         {
            return FError;
         }
      }
      public object GetParam(string name, object empty)
      {
         object obj = null;
         if (FOperation != null) FOperation.Params.TryGetValue(name, out obj);
         return obj == null ? empty : obj;
      }
      public object GetResult(string name, object empty)
      {
         object obj = null;
         if (FOperation != null) FOperation.Results.TryGetValue(name, out obj);
         return obj == null ? empty : obj;
      }

      public NetworkOperationEventArgs(NetworkOperation operation, ServiceOperationException error)
      {
         FError = error;
         FOperation = operation;
      }
      public NetworkOperationEventArgs(NetworkOperation operation, OperationState state, ServiceOperationException error)
      {
         FError = error;
         FState = state;
         FOperation = operation;
         if (operation != null) operation.State = state;
      }
   }

   public class ParticipantsChangedEventArgs : EventArgs
   {
      public User User;
      public Account Owner;

      public bool Add;
      public bool Show;
      public bool Block;
      public bool Remove;

      public ParticipantsChangedEventArgs(User user, Account owner, bool show)
      {
         User = user;
         Owner = owner;

         Add = true;
         Show = show;
         Block = false;
         Remove = false;
      }

      public ParticipantsChangedEventArgs(User user, Account owner, bool remove, bool block, bool show)
      {
         User = user;
         Owner = owner;

         Add = false;
         Show = show;
         Block = block;
         Remove = remove;
      }
   }

   public class MediaSessionTypeAddedEventArgs : EventArgs
   {
      public readonly MediaSessionTypeInfo TypeInfo;

      public MediaSessionTypeAddedEventArgs(MediaSessionTypeInfo typeInfo)
      {
         TypeInfo = typeInfo;
      }
   }

   public class SaveAccountDataEventArgs : NetworkOperationEventArgs
   {
      public readonly SaveAccountActions Actions;

      public SaveAccountDataEventArgs(SaveAccountActions actions, NetworkOperation operation, OperationState state, ServiceOperationException error)
         : base(operation, state, error)
      {
         Actions = actions;
      }
   }

   public class SaveMediaSessionEventArgs : NetworkOperationEventArgs
   {
      public readonly IMediaSession Session;

      public readonly SaveMediaSessionActions Actions;

      public SaveMediaSessionEventArgs(IMediaSession session, SaveMediaSessionActions actions, NetworkOperation operation, OperationState state, ServiceOperationException error)
         : base(operation, state, error)
      {
         Session = session;
         Actions = actions;
      }
   }

   public class MediaSessionUpdateEventArgs : NetworkOperationEventArgs
   {
      public readonly object Target;

      public readonly IMediaSession Session;

      public readonly SaveMediaSessionActions Actions;

      public MediaSessionUpdateEventArgs(IMediaSession session, SaveMediaSessionActions actions, object target)
         : base(null, OperationState.None, null)
      {
         Target = target;
         Session = session;
         Actions = actions;
      }
   }

   public class MessagingOperationEventArgs : NetworkOperationEventArgs
   {
      ServiceMessage FEventMessage;
      ServiceMessage FReplyMessage;
      ServiceMessage FRequestMessage;
      PolicyRule FAppliedRule = PolicyRule.None;

      public PolicyRule AppliedRule
      {
         get
         {
            return FAppliedRule;
         }
         set
         {
            FAppliedRule = value;
         }
      }
      public ServiceMessage EventMessage
      {
         get
         {
            return FEventMessage != null ? FEventMessage : (FReplyMessage != null ? FReplyMessage : FRequestMessage);
         }
      }
      public ServiceMessage ReplyMessage
      {
         get
         {
            return FReplyMessage;
         }
      }
      public ServiceMessage RequestMessage
      {
         get
         {
            return FRequestMessage;
         }
      }

      public MessagingOperationEventArgs(NetworkOperation operation, ServiceOperationException error)
         : base(operation, error)
      {
         FEventMessage = null;
      }

      public MessagingOperationEventArgs(ServiceMessage eventMessage)
         : base(null, OperationState.None, null)
      {
         FEventMessage = eventMessage;
      }

      public MessagingOperationEventArgs(ServiceMessage requestMessage, ServiceMessage replyMessage)
         : base(null, OperationState.None, null)
      {
         FReplyMessage = replyMessage;
         FRequestMessage = requestMessage;
      }

      public MessagingOperationEventArgs(ServiceMessage eventMessage, NetworkOperation operation, OperationState state, ServiceOperationException error)
         : base(operation, state, error)
      {
         FEventMessage = eventMessage;
      }

      public MessagingOperationEventArgs(ServiceMessage requestMessage, ServiceMessage replyMessage, NetworkOperation operation, OperationState state, ServiceOperationException error)
         : base(operation, state, error)
      {
         FReplyMessage = replyMessage;
         FRequestMessage = requestMessage;
      }
   }
}